###########################################
#  Primary Divisions: How Voters Evaluate Policy and Group Differences in Intra-Party Contests
#   - Forthcoming at The Journal of Politics
#   - Henderson et al 2021
#
###########################################
#  - code by S. Goggin & J. Henderson
########################################################
# This file produces figures for marginal means estimates of candidate choices
########################################################

#dirs="~/Dropbox/replication0/"
#dirs should be set here or in runR.R 

rm(list=ls()[which(ls()!='dirs')])
library(ggplot2)
library(stringr)
library(cregg)

# messy function to reorder by some estimate value
lableOrder=function(xmat,labels,label.groups,omits,o.column){

	# denote which label is to be omitted on the label
	for(i in 1:length(omits)){
		labels[which(labels==omits[i])]=paste('omit',labels[which(labels==omits[i])],sep='_')
	}

	# break groups into levels
	un_group=unique(label.groups)

	# this is the item to sort on, typically global or independent
	xm=xmat[,o.column]

	# vector which will contain row order
	xo=1:length(xm)

	# rearranging roworder within level
	for(j in 1:length(un_group)){
		ix=which(label.groups==un_group[j])
		if(length(ix)>2){
			ix=ix[!grepl(labels[ix],pattern='omit')]
			xo[ix]=xo[ix][order(xm[ix])]
		}
	}
	return(xmat[xo,])
}

reOrder=function(x,o){
	ix=array(NA,nrow(x))
	for(i in 1:length(o)){
		ix[i]=which(x$iv_order==o[i])
	}
	return(x[ix,])
}

setwd(dirs)
load("data/cces_stacked_unmatched.Rdata")

###########################################
###First, need to stack based on candidates, not just candidate pairs (and also get text out for labels later)

#This has leaners as independents, which is incorrect
#cces_stacked$pid3clean <- ifelse(cces_stacked$pid3=="Democrat",-1,ifelse(cces_stacked$pid3=="Republican",1,0))

library(car)


load('data/data_matrix_scored.Rdata')
candidate_matrix=data_matrix

###########################################
###Then, produce models w/ Clustered SEs

#Function from: http://scholar.byu.edu/jgubler/book/clustered-standard-errors-r
#Need this for clustered standard errors
clse.f <- function(dat,fm, cluster){
 require(sandwich)
 require(lmtest)
 not <- attr(fm$model,"na.action")
if( ! is.null(not)){
  cluster <- cluster[-not]
    dat <- dat[-not,]
}
 with(dat,{
 M <- length(unique(cluster))
 N <- length(cluster)
 K <- fm$rank #doF
 #dfc <- (M/(M-1))*((N-1)/(N-K))
 dfc <- ((N-1)/(N-K))
 # estfun is :: residuals(fm) * X
 # summing estimating function to the cluster || i.e., summing residuals to the cluster level  over units in cluster
 uj <- apply(estfun(fm),2, function(x) tapply(x, cluster, sum));
 vcovCL <- dfc*sandwich(fm, meat=crossprod(uj)/N)
 coeftest(fm, vcovCL)
 }
 )
}

############################################################
############################################################
###Now for Primary Elections (by PID)

vote <- subset(candidate_matrix,candidate_matrix$conjoints==3|candidate_matrix$conjoints==8)
vote$pty <- ifelse(vote$conjoints==3,0,1)

#vote$wt=1/vote$wt

# adjust
#vote$gender[which(vote$gender=='Male')]='b_Male'
#vote$gender[which(vote$gender=='Female')]='a_Female'

for(j in 8:16){
	vote[,j]=as.factor(vote[,j])
}
vote2=vote1=vote
vote1$issue0=vote1$issue1
vote2$issue0=vote2$issue2
vote=rbind(vote1,vote2)
vote$wt=1/vote$wt

# issues
labels0=c(
"Defend traditional marriage and religious beliefs",
"Protect the lives of the unborn",
"Strengthen border security to stop illegal immigration",
"Strengthen our military and national defense",
"Protect gun owners' rights to defend themselves and others",
"Expand domestic oil and gas production through drilling",
"Cut taxes on income and capital gains for all",
"Toughen sentences and penalties for criminals",
"Prevent and prosecute abuse of government assistance programs",
"Protect jobs and industry from unfair foreign trade",
"Promote expanding free trade agreements",
"Reduce the size of military and number of military bases",
"Regulate CO2 emissions to combat global warming",
"Strengthen gun control through commonsense restrictions",
"Reform policing and stop racial profiling",
"Raise taxes on those making more than $250,000 a year",
"Protect a woman's right to choose",
"Provide a path to citizenship for undocumented immigrants",
"Expand government and unemployment assistance for those in need",
"Defend the rights of LGBT individuals"
)

labels1=c(
"a. Defend traditional marriage",
"b. Protect the unborn",
"c. Strengthen border security",
"d. Strengthen our military",
"e. Protect gun owners' rights",
"f. Expand domestic oil production",
"g. Cut taxes on income for all",
"h. Toughen sentences and penalties",
"i. Prosecute abuse of government programs",
"j. Protect jobs and industry",
"k. Promote free trade agreements",
"l. Reduce the size of military",
"m. Regulate CO2 emissions",
"n. Strengthen gun control",
"o. Reform policing",
"p. Raise taxes on the wealthy",
"q. Protect a woman's right to choose",
"r. Provide a path to citizenship",
"s. Expand unemployment assistance",
"t. Defend the rights of LGBT individuals"
)

#"a. Defend traditional marriage and religious beliefs",
#"b. Protect the lives of the unborn",
#"c. Strengthen border security to stop illegal immigration",
#"d. Strengthen our military and national defense",
#"e. Protect gun owners' rights to defend themselves and others",
#"f. Expand domestic oil and gas production through drilling",
#"g. Cut taxes on income and capital gains for all",
#"h. Toughen sentences and penalties for criminals",
#"i. Prevent and prosecute abuse of government assistance programs",
#"j. Protect jobs and industry from unfair foreign trade",
#"k. Promote expanding free trade agreements",
#"l. Reduce the size of military and number of military bases",
#"m. Regulate CO2 emissions to combat global warming",
#n. Strengthen gun control through commonsense restrictions",
#"o. Reform policing and stop racial profiling",
#"p. Raise taxes on those making more than $250,000 a year",
#"q. Protect a woman's right to choose",
#"r. Provide a path to citizenship for undocumented immigrants",
#"s. Expand government and unemployment assistance for those in need",
#"t. Defend the rights of LGBT individuals"

vote$issue0=as.character(vote$issue0)
for(i in 1:length(labels0)){
	vote$issue0[which(vote$issue0==labels0[i])]=labels1[i]
}
vote$issue0=as.factor(vote$issue0)

# record
labels0=levels(vote$record)
labels1=c(
	"e. Help my constituents",
	"a. Refuse to compromise my principles",
	"c. Secure powerful committee appointment",
	"b. Stand with my party",
	"d. Work across the aisle"
)

#"e. Help my constituents get the benefits they deserve",
#"a. Refuse to compromise my principles even when it means taking on my party",
#"c. Secure appointment to a powerful legislative committee",
#"b. Stand with my party to do what's right",
#"d. Work across the aisle to get things done"

vote$record=as.character(vote$record)
for(i in 1:length(labels0)){
	vote$record[which(vote$record==labels0[i])]=labels1[i]
}
vote$record=as.factor(vote$record)

# endorsements
labels0=levels(vote$endorsements)
labels1=c(
	"f. Business groups",
	"b. Christian groups",
  "i. Civil rights groups",
	"d. Energy groups",
  "l. Environmental groups",
	"k. Gun control groups",
  "c. Gun rights groups",
	"h. Labor unions",
  "m. Major area newspapers",
	"j. Reproductive rights groups",
  "e. Tax reform groups",
 	"a. Tea Party groups",
 	"g. Veterans groups"
)

#"f. Business groups (Chamber of Commerce, Small Business Associations)",
#"b. Christian groups (Family Research Council, Focus on the Family)",
#"i. Civil rights groups (key figures in the NAACP and Urban League)",
#"d. Energy groups (American Petroleum and Mining Associations)",
#"l. Environmental groups (Sierra Club, Natural Resources Defense Council)",
#"k. Gun control groups (Coalition to Stop Gun Violence, Brady Campaign)",
#"c. Gun rights groups (NRA, Gun Owners of America)",
#"h. Labor unions (AFL-CIO, SEIU)",
#"m. Major area newspapers (Tribune, Herald)",
#"j. Reproductive rights groups (Planned Parenthood, NARAL)",
#"e. Tax reform groups (Club for Growth, Americans for Tax Reform)",
#"a. Tea Party groups (FreedomWorks, Tea Party Patriots)",
#"g. Veterans groups (American Legion, American Veterans)"

vote$endorsements=as.character(vote$endorsements)
for(i in 1:length(labels0)){
	vote$endorsements[which(vote$endorsements==labels0[i])]=labels1[i]
}
vote$endorsements=as.factor(vote$endorsements)

# personality
labels0=levels(vote$personality)
labels1=c(
 "e. Compassionate",
 "h. Decent"        ,
 "b. Empathetic"    ,
 "g. Inspiring"     ,
 "f. Intelligent"   ,
 "d. Knowledgeable" ,
 "c. Moral"         ,
 "a. Strong Leader"
)

vote$personality=as.character(vote$personality)
for(i in 1:length(labels0)){
	vote$personality[which(vote$personality==labels0[i])]=labels1[i]
}
vote$personality=as.factor(vote$personality)


# occupation
labels0=levels(vote$occupation)
labels1=c(
	"j. Attorney"  ,
	"f. CEO"        ,
	"a. City Council Member" ,
	"d. Factory Foreman"      ,
	"g. Farmer"               ,
	"e. Former US Army Major",
	"c. Political Staffer"    ,
	"b. Small Business Owner" ,
	"h. State Legislator"     ,
	"i. Teacher"
)

vote$occupation=as.character(vote$occupation)
for(i in 1:length(labels0)){
	vote$occupation[which(vote$occupation==labels0[i])]=labels1[i]
}
vote$occupation=as.factor(vote$occupation)


# religion
labels0=levels(vote$religion)
labels1=c(
	"b. Catholic"               ,
	"a. Evangelical Protestant" ,
	"d. None Listed"            ,
	"c. Protestant"
)

vote$religion=as.character(vote$religion)
for(i in 1:length(labels0)){
	vote$religion[which(vote$religion==labels0[i])]=labels1[i]
}
vote$religion=as.factor(vote$religion)


# race
labels0=levels(vote$race)
labels1=c(
	"b. Black"    ,
	"a. Hispanic" ,
	"c. White"
)

vote$race=as.character(vote$race)
for(i in 1:length(labels0)){
	vote$race[which(vote$race==labels0[i])]=labels1[i]
}
vote$race=as.factor(vote$race)


# gender
labels0=levels(vote$gender)
labels1=c(
	"a. Female",
	"b. Male"
)

vote$gender=as.character(vote$gender)
for(i in 1:length(labels0)){
	vote$gender[which(vote$gender==labels0[i])]=labels1[i]
}
vote$gender=as.factor(vote$gender)


reps <- subset(vote, vote$pid3==1)
dems <- subset(vote, vote$pid3==-1)
inds <- subset(vote, vote$pid3==0)

require(qdapRegex)

reps$endorsement=rm_between(reps$endorsement, "(", ")", extract = F)
dems$endorsement=rm_between(dems$endorsement, "(", ")", extract = F)
inds$endorsement=rm_between(inds$endorsement, "(", ")", extract = F)
#dv_choice is the vote choice variable
# pty is included for independents here, otherwise of course NAs out.
ft = dv_choice ~ gender + race + religion + occupation + personality + endorsements + record + issue0

attach(reps)
w=weighted.mean(reps$dv_choice,w=reps$wt)
pdf('appendix/figures/leeperR.pdf',height=10)
plot(mm(reps, ft, id = ~respondent, weights = ~wt), hline=20,vline = w,xlim=c(w-.25,w+.25))

dev.off()
detach(reps)

attach(dems)
w=weighted.mean(dems$dv_choice,w=dems$wt)
pdf('appendix/figures/leeperD.pdf',height=10)
plot(mm(dems, ft, id = ~respondent, weights = ~wt), vline = w,xlim=c(w-.25,w+.25))
dev.off()
detach(dems)

inds$pty[which(inds$pty==1)]='Republican'
inds$pty[which(inds$pty==0)]='Democrat'
inds$pty=as.factor(inds$pty)
attach(inds)
w=weighted.mean(inds$dv_choice,w=inds$wt)
ft = dv_choice ~ gender + race + religion + occupation + personality + endorsements + record + issue0 + pty
pdf('appendix/figures/leeperI.pdf',height=10)
plot(mm(inds, ft, id = ~respondent, weights = ~wt), vline = w,xlim=c(w-.25,w+.25))
dev.off()
detach(inds)

# choice_primary.R
#system("convert -density 600 figures/choice_both_twoparty.pdf -quality 300 figures/choice_both_twoparty.png")
#system("convert -density 600 figures/choice_inparty_twoparty.pdf -quality 300 figures/choice_inparty_twoparty.png")
#system("convert -density 600 figures/choice_outparty_twoparty.pdf -quality 300 figures/choice_outparty_twoparty.png")
# END
